/**
 * @description 恢复资源弹窗
 */

import React from 'react';
import PropTypes from 'prop-types';
import { Dialog, Form, Field, Input, Message } from '@teamix/ui';
import exceed from 'utils/apimap';
import { checkGroupNamePath, checkProjectName } from 'api/index.js';
import debounce from 'lodash.debounce';
import ListLoading from 'atComponents/ListLoading';
import AddonBeforeInput from 'components/addonBeforeInput';
import intl from '../../../../../../../locale';

const FormItem = Form.Item;
const formItemLayout = {
  labelCol: {
    span: 6,
  },

  wrapperCol: {
    span: 14,
  },
};

export default class GroupModal extends React.Component {
  static propTypes = {
    trigger: PropTypes.element,
    successFn: PropTypes.func,
    closeModal: PropTypes.func,
    isModalOepn: PropTypes.bool,
    record: PropTypes.object,
  };

  static defaultProps = {
    trigger: null,
    successFn: () => {},
    closeModal: () => {},
    isModalOepn: false,
    record: null,
  };

  constructor(props) {
    super(props);
    this.field = new Field(this);
    this.state = {
      submitting: false,
      isModalOpen: false,
      // 初始验证Ok
      isInitVerifyOk: false,
      // 组不存在时，显示信息
      errorInfo: '',
      isLoading: true,
    };

    this.checkResourceWithDebounce = debounce(this.checkResource, 500);
  }

  static getDerivedStateFromProps(props) {
    if (props.trigger) {
      return {};
    }
    return {
      isModalOpen: props.isModalOpen,
    };
  }

  componentDidMount() {
    const { record } = this.props;
    if (!record) {
      return;
    }
    const { name, path } = record.resource || {};
    this.checkResource(
      {
        name,
        path,
      },

      (err, response) => {
        this.setState({
          isInitVerifyOk: !err,
          errorInfo:
            err && response && response.errorCode === 'SYSTEM_ILLEGAL_ARGUMENT_ERROR' ? err : '',
          isLoading: false,
        });

        this.field.setValue('path', path);
      },
    );
  }

  showModal = () => {
    this.setState({
      isModalOpen: true,
    });
  };

  checkResource = ({ name, path }, callback) => {
    const { record } = this.props;
    if (!record) {
      return;
    }
    const { source_type, resource } = record;
    const isGroup = source_type === 'Namespace';
    const namespace_id = resource[isGroup ? 'parent_id' : 'namespace_id'];
    const req = isGroup ? checkGroupNamePath : checkProjectName;
    req({
      name,
      path,
      namespace_id,
      contains_recycled: true,
    })
      .then(() => {
        callback && callback();
      })
      .catch((err) => {
        const response = JSON.parse(err.responseText);
        const errCause = response.cause;
        callback && callback(errCause, response);
      });
  };

  pathValidator = (rule, value, callback) => {
    if (!value || /^[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,}$/.test(value)) {
      this.checkResourceWithDebounce(
        {
          name: value,
          path: value,
        },

        callback,
      );
    } else {
      callback(
        intl.get({
          id: 'code-assets.trashes.containers.recoverModal.ItCanOnlyContainLetters',
          defaultMessage: "只能包含字母和数字、 '_'、 '.'和'-'，且只能以字母、数字或'_'开头",
        }),
      );
    }
  };

  /**
   * 关闭事件
   * @param {*} needReq 是否需要重新请求，点击Ok才需要
   */
  onClose = (needReq) => {
    this.setState({
      isModalOpen: false,
    });

    this.props.closeModal(needReq);
  };

  handleOk = () => {
    this.field.validate((errors) => {
      if (!errors) {
        if (this.state.submitting) {
          return;
        }
        this.setState({ submitting: true });
        const formData = this.field.getValues();
        this.formSubmit(formData, () => {
          this.setState({ submitting: false });
          this.onClose(true);
        });
      }
    });
  };

  // 创建子组
  formSubmit = (formData, cb) => {
    const { record } = this.props;
    const { source_type, resource } = record;
    const isGroup = source_type === 'Namespace';

    exceed
      .fetch({
        api: isGroup ? 'group.trashes.restore' : 'project.trashes.restore',
        params: {
          id: resource.id,
          path: formData.path,
          name: resource.name,
        },
      })
      .then((result) => {
        if (result && result.result) {
          Message.success({
            title: isGroup
              ? intl.get({
                  id: 'code-assets.trashes.containers.recoverModal.TheCodeGroupIsRestored',
                  defaultMessage: '代码组恢复成功',
                })
              : intl.get({
                  id: 'code-assets.trashes.containers.recoverModal.TheCodeLibraryIsRestored',
                  defaultMessage: '代码库恢复成功',
                }),
          });
        } else {
          Message.error({
            title: isGroup
              ? intl.get({
                  id: 'code-assets.trashes.containers.recoverModal.CodeGroupRecoveryFailed',
                  defaultMessage: '代码组恢复失败',
                })
              : intl.get({
                  id: 'code-assets.trashes.containers.recoverModal.CodeBaseRecoveryFailed',
                  defaultMessage: '代码库恢复失败',
                }),
          });
        }
        cb && cb();
      })
      .fail(() => {
        cb && cb();
        Message.error({
          title: isGroup
            ? intl.get({
                id: 'code-assets.trashes.containers.recoverModal.CodeGroupRecoveryFailed',
                defaultMessage: '代码组恢复失败',
              })
            : intl.get({
                id: 'code-assets.trashes.containers.recoverModal.CodeBaseRecoveryFailed',
                defaultMessage: '代码库恢复失败',
              }),
        });
      });
  };

  /**
   * 获取路径
   * @param {*} path_with_namespace 路径
   * @param {*} needName 是否需要携带名称
   */
  getPath = (path_with_namespace, needName = false) => {
    const arr = path_with_namespace.split('/');
    !needName && arr.pop();
    const prefix = arr.join('/');
    return prefix;
  };

  render() {
    const { init } = this.field;
    const { isLoading, isInitVerifyOk, errorInfo, submitting } = this.state;
    const { record } = this.props;
    const { source_type, resource } = record;
    const isGroup = source_type === 'Namespace';
    let pathPrefix = '';
    if (record && record.resource && record.resource.path_with_namespace) {
      const { path_with_namespace } = record.resource;
      pathPrefix = this.getPath(path_with_namespace);
    }

    return (
      <React.Fragment>
        {this.state.isModalOpen ? (
          <Dialog
            title={intl.get({
              id: 'code-assets.trashes.containers.recoverModal.RestoreContent',
              defaultMessage: '恢复内容',
            })}
            visible
            style={{ width: '400px' }}
            onOk={() => {
              if (errorInfo) {
                this.onClose();
              } else {
                this.handleOk();
              }
            }}
            onCancel={() => {
              this.onClose();
            }}
            onClose={() => {
              this.onClose();
            }}
            className="trash-modal"
            okProps={{
              loading: !!submitting,
              children: errorInfo
                ? intl.get({
                    id: 'code-assets.trashes.containers.recoverModal.ISee',
                    defaultMessage: '我知道了',
                  })
                : intl.get({
                    id: 'code-assets.trashes.containers.recoverModal.Recovery',
                    defaultMessage: '恢复',
                  }),
            }}
            cancelProps={{
              style: {
                display: errorInfo ? 'none' : 'inline-block',
              },
            }}
          >
            {isLoading ? (
              <ListLoading />
            ) : (
              <Form {...formItemLayout} field={this.field} labelAlign="top">
                {isInitVerifyOk ? (
                  <div style={{ padding: '8px 0', wordBreak: 'break-all' }}>
                    {intl.get({
                      id: 'code-assets.trashes.containers.recoverModal.ConfirmTheContentToBe',
                      defaultMessage: '确认恢复内容到',
                    })}
                    {this.getPath(resource.path_with_namespace, true)} ？
                  </div>
                ) : (
                  <React.Fragment>
                    {errorInfo ? (
                      <div style={{ padding: '8px 0' }}>{errorInfo}</div>
                    ) : (
                      <FormItem
                        label={intl.get({
                          id: 'code-assets.trashes.containers.recoverModal.TheNameAlreadyExistsPlease',
                          defaultMessage: '名称已存在，请重命名后确认恢复',
                        })}
                      >
                        {pathPrefix ? (
                          <AddonBeforeInput
                            autoFocus
                            maxLength={isGroup ? 30 : 100}
                            hasLimitHint
                            addonTextBefore={`${pathPrefix}/`}
                            placeholder={
                              isGroup
                                ? intl.get({
                                    id: 'code-assets.trashes.containers.recoverModal.EnterTheCodeGroupPath',
                                    defaultMessage: '请输入代码组路径',
                                  })
                                : intl.get({
                                    id: 'code-assets.trashes.containers.recoverModal.EnterTheCodeLibraryPath',
                                    defaultMessage: '请输入代码库路径',
                                  })
                            }
                            style={{ width: '100%' }}
                            {...init('path', {
                              initValue: record && record.resource && record.resource.path,
                              rules: [
                                {
                                  required: true,
                                  message: intl.get({
                                    id: 'code-assets.trashes.containers.recoverModal.ThisParameterIsRequired',
                                    defaultMessage: '该项为必填项',
                                  }),
                                },
                                {
                                  validator: this.pathValidator,
                                },
                              ],
                            })}
                          />
                        ) : (
                          <Input
                            autoFocus
                            maxLength={isGroup ? 30 : 100}
                            hasLimitHint
                            placeholder={
                              isGroup
                                ? intl.get({
                                    id: 'code-assets.trashes.containers.recoverModal.EnterTheCodeGroupPath',
                                    defaultMessage: '请输入代码组路径',
                                  })
                                : intl.get({
                                    id: 'code-assets.trashes.containers.recoverModal.EnterTheCodeLibraryPath',
                                    defaultMessage: '请输入代码库路径',
                                  })
                            }
                            {...init('path', {
                              initValue: record && record.resource && record.resource.path,
                              rules: [
                                {
                                  required: true,
                                  message: intl.get({
                                    id: 'code-assets.trashes.containers.recoverModal.ThisParameterIsRequired',
                                    defaultMessage: '该项为必填项',
                                  }),
                                },

                                {
                                  validator: this.pathValidator,
                                },
                              ],
                            })}
                          />
                        )}
                      </FormItem>
                    )}
                  </React.Fragment>
                )}
              </Form>
            )}
          </Dialog>
        ) : null}
        {!!this.props.trigger &&
          React.cloneElement(this.props.trigger, { onClick: this.showModal })}
      </React.Fragment>
    );
  }
}
